package com.iocup.keybastion.spring.starter.config;


import com.iocup.keybastion.authorize.parser.AuthAnnotationParser;
import com.iocup.keybastion.configuration.*;
import com.iocup.keybastion.core.HttpActionAdapter;
import com.iocup.keybastion.core.SecurityEngine;
import com.iocup.keybastion.sso.config.SsoApiProperties;
import com.iocup.keybastion.sso.config.SsoProperties;
import com.iocup.keybastion.utils.AuthUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
@Conditional({EnabledSecurityCondition.class})
@ComponentScan("com.iocup.keybastion")
public class SecurityAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(SecurityConfiguratorAdapter.class)
    public SecurityConfiguratorAdapter securityConfiguratorAdapter() {
        return new DefaultSecurityConfiguratorAdapter();
    }

    @Bean
    @ConfigurationProperties(prefix = "security.authentication.token")
    public TokenProperties tokenProperties() {
        return new TokenProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "security.authentication.credentials")
    public TokenExtractProperties tokenExtractConfigurator() {
        return new TokenExtractProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "security.matching")
    public SecurityProperties securityProperties() {
        return new SecurityProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "security.authorize")
    public PermissionProperties permissionProperties() {
        return new PermissionProperties();
    }


    @Bean
    @ConfigurationProperties(prefix = "security.sso")
    public SsoProperties ssoProperties() {
        return new SsoProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "security.sso.api")
    public SsoApiProperties ssoApiProperties() {
        return new SsoApiProperties();
    }

    @Bean
    @ConditionalOnMissingBean(HttpActionAdapter.class)
    public HttpActionAdapter httpActionAdapter(SecurityEngine securityEngine) {
        return securityEngine.getHttpConfigurator().getHttpActionAdapter();
    }


    @Bean
    public SecurityEngine securityEngine(
            List<SecurityConfiguratorAdapter> securityConfiguratorAdapter,
            PermissionProperties permissionProperties,
            SecurityProperties securityProperties,
            TokenProperties tokenProperties) {
        SecurityEngine securityEngine = new SecurityEngine()
                .securityConfiguratorAdapter(securityConfiguratorAdapter);
        securityEngine.getAuthenticationConfigurator().tokenProperties(tokenProperties).securityProperties(securityProperties);
        securityEngine.getAuthorizationConfigurator().permissionProperties(permissionProperties);
        securityEngine.init();
        AuthUtils.setSecurityEngine(securityEngine);
        return securityEngine;
    }

    @Bean
    public AuthAnnotationParserProcessor authAnnotationParserProcessor() {
        return new AuthAnnotationParserProcessor();
    }


    @Bean
    public AuthAnnotationParser authAnnotationParser(SecurityEngine securityEngine) {
        return securityEngine.getAuthorizationConfigurator().getAuthAnnotationParser();
    }


}
